package packgui;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Observable;
import java.util.Observer;
import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.AbstractTableModel;
import packexceptions.*;
import packmail.MailConfirmation;
import packmodele.*;

/**
 * Panel gérant l'affichage du panier d'un utilisateur
 * 
 * @author Paulino
 * 
 */
public class PanelVuePanier extends JPanel implements Observer
{
	private static final long serialVersionUID = 1L;
	private JLabel jlPrixTot;
	private JScrollPane jScrollPane;
	private TmListeProduit tmListeProduit;
	private JTable jtProduits;
	private JTextField jtfTotal;
	private PanelBoutons pBoutons;

	private EnsembleProduits panier;

	public PanelVuePanier()
	{
		Systeme.getInstance().getPanier().addObserver(this);
		init();
	}

	public void init()
	{
		GroupLayout layout = new GroupLayout(this);
		setLayout(layout);

		GroupLayout.SequentialGroup horizon = layout.createSequentialGroup();
		layout.setHorizontalGroup(horizon);
		GroupLayout.ParallelGroup vgroup1 = layout.createParallelGroup();
		horizon.addGroup(vgroup1);
		// vgroup1.addComponent(getPTypeProduit());
		vgroup1.addComponent(getjScrollPane());
		horizon.addComponent(getPBoutons(), PanelBoutons.LARGEUR,
				PanelBoutons.LARGEUR, PanelBoutons.LARGEUR);
		vgroup1.addComponent(getJlPrixTot());
		vgroup1.addComponent(getJtfTotal());

		GroupLayout.SequentialGroup vertical = layout.createSequentialGroup();
		layout.setVerticalGroup(vertical);
		// vertical.addComponent(getPTypeProduit());
		GroupLayout.ParallelGroup hgroup = layout.createParallelGroup();
		vertical.addGroup(hgroup);
		hgroup.addComponent(getjScrollPane());
		hgroup.addComponent(getPBoutons());
		vertical.addComponent(getJlPrixTot());
		vertical.addComponent(getJtfTotal(), 30, 30, 30);

	}

	/**
	 * Label affichant le montant total du panier
	 * 
	 * @author Cedric
	 */
	public JLabel getJlPrixTot()
	{
		if (jlPrixTot == null)
		{
			jlPrixTot = new JLabel("Total : ");
		}
		return jlPrixTot;
	}

	public JTextField getJtfTotal()
	{
		if (jtfTotal == null)
		{
			jtfTotal = new JTextField("0 €");
			jtfTotal.setEditable(false);
		}
		return jtfTotal;
	}

	public JScrollPane getjScrollPane()
	{
		if (jScrollPane == null)
		{
			jScrollPane = new JScrollPane(getJtProduits());
		}
		return jScrollPane;
	}

	public TmListeProduit getTmListeProduit()
	{
		if (tmListeProduit == null)
		{
			tmListeProduit = new TmListeProduit();
		}
		return tmListeProduit;
	}

	public JTable getJtProduits()
	{
		if (jtProduits == null)
		{
			jtProduits = new JTable(getTmListeProduit());
			jtProduits.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		}
		return jtProduits;
	}

	public PanelBoutons getPBoutons()
	{
		if (pBoutons == null)
		{
			pBoutons = new PanelBoutons();
		}
		return pBoutons;
	}

	@Override
	public void update(Observable arg0, Object arg1)
	{
		// calcul du nouveau prix total
		getJtfTotal().setText(panier.getPrixTotal() + " €");
		getTmListeProduit().fireTableDataChanged();

		if (panier.getNombreProduits() > 0)
		{
			getPBoutons().getJbConfirmer().setEnabled(true);
		}
		else
		{
			getPBoutons().getJbConfirmer().setEnabled(false);
		}
	}

	/**
	 * Effectue l'achat du panier, envoie le mail de confirmation, et affiche
	 * les messages d'erreur/de confirmation.
	 */
	public void acheter()
	{
		if (panier.getNombreProduits() == 0)
		{
			System.err.println("Panier vide!");
			return;
		}

		try
		{
			Systeme.getInstance().acheter(panier);
			new MailConfirmation(panier).envoyer();
			JOptionPane
					.showMessageDialog(FramePrincipale.getInstance(),
							"Achat effectué!", "Achat",
							JOptionPane.INFORMATION_MESSAGE);
			panier.vider();
		}
		catch (QuantiteInsuffisanteException e)
		{
			JOptionPane.showMessageDialog(FramePrincipale.getInstance(),
					e.getMessage(), "Erreur", JOptionPane.ERROR_MESSAGE);
		}
		catch (ObjetInconnuException e)
		{
			JOptionPane.showMessageDialog(FramePrincipale.getInstance(),
					e.getMessage(), "Erreur", JOptionPane.ERROR_MESSAGE);
		}
	}

	public class TmListeProduit extends AbstractTableModel
	{
		private static final long serialVersionUID = 1L;

		public final String[] colonnes = { "Type", "Titre", "Prix (euro)",
				"Quantité" };

		public TmListeProduit()
		{
			panier = Systeme.getInstance().getPanier();
		}

		public int getColumnCount()
		{
			return colonnes.length;
		}

		@Override
		public boolean isCellEditable(int rowIndex, int columnIndex)
		{
			return false;
		}

		@Override
		public int getRowCount()
		{
			return panier.getNombreProduits();
		}

		@Override
		public Object getValueAt(int ligne, int col)
		{
			Detail detail = panier.getDetail(ligne);

			if (detail != null)
			{
				switch (col)
				{
				case 0:
					return (Object) detail.getProduit().getClass()
							.getSimpleName();
				case 1:
					return (Object) detail.getProduit().getTitre();
				case 2:
					return (Object) detail.getProduit().getPrix();
				case 3:
					return (Object) (detail.getQuantite());
				default:
					return null;
				}
			}
			else
			{
				return null;
			}
		}

		@Override
		public String getColumnName(int column)
		{
			if (column >= 0 && column < colonnes.length)
			{
				return colonnes[column];
			}
			else
			{
				return "???";
			}
		}

		public Class<?> getColumnClass(int column)
		{
			if (column >= 0 && column < colonnes.length)
			{
				switch (column)
				{
				case 0:
					return String.class;
				case 1:
					return String.class;
				case 2:
					return Double.class;
				case 3:
					return Integer.class;
				}
			}
			return Object.class;
		}
	}

	public class PanelBoutons extends JPanel
	{
		private static final long serialVersionUID = 1L;

		public static final int LARGEUR = 150;
		private JButton jbCatalogue, jbRetirer, jbDetails, jbConfirmer,
				jbQuantite;

		public PanelBoutons()
		{
			setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
			add(getJbCatalogue());
			add(getJbDetails());
			add(getJbQuantite());
			add(getJbRetirer());
			add(getJbConfirmer());

			getJbDetails().setEnabled(false);
			getJbQuantite().setEnabled(false);
			getJbRetirer().setEnabled(false);
			getJbConfirmer().setEnabled(false);

			getJtProduits().getSelectionModel().addListSelectionListener(
					new ListSelectionListener()
					{

						@Override
						public void valueChanged(ListSelectionEvent event)
						{
							if (getJtProduits().getSelectedRow() > -1)
							{
								getJbDetails().setEnabled(true);
								getJbQuantite().setEnabled(true);
								getJbRetirer().setEnabled(true);
							}
							else
							{
								getJbDetails().setEnabled(false);
								getJbQuantite().setEnabled(false);
								getJbRetirer().setEnabled(false);
							}
						}
					});
		}

		public JButton getJbCatalogue()
		{
			if (jbCatalogue == null)
			{
				jbCatalogue = new JButton("Catalogue");
				jbCatalogue.addActionListener(new ActionListener()
				{

					@Override
					public void actionPerformed(ActionEvent arg0)
					{
						FramePrincipale.getInstance().setVue(
								FramePrincipale.PANEL_PRODUITS);
					}
				});
			}
			return jbCatalogue;
		}

		/**
		 * Bouton permettant d'afficher les détails du produit sélectionné
		 * 
		 * @author Cedric
		 */
		public JButton getJbDetails()
		{
			if (jbDetails == null)
			{
				jbDetails = new JButton("Détails");
				jbDetails.addActionListener(new ActionListener()
				{
					public void actionPerformed(ActionEvent e)
					{
						FrameDetail detail = new FrameDetail(panier.getDetail(
								getJtProduits().getSelectedRow()).getProduit(),
								false);
						detail.setLocationRelativeTo(PanelVuePanier.this);
						detail.setVisible(true);
					}
				});
			}
			return jbDetails;
		}

		/**
		 * Bouton permettant de retirer un produit du panier
		 * 
		 * @author Cedric
		 */
		public JButton getJbRetirer()
		{
			if (jbRetirer == null)
			{
				jbRetirer = new JButton("Retirer");
				jbRetirer.addActionListener(new ActionListener()
				{
					public void actionPerformed(ActionEvent e)
					{
						int index = getJtProduits().getSelectedRow();

						if (index > -1)
						{
							try
							{
								panier.supprimerProduit(panier.getDetail(index)
										.getProduit());
								System.out.println("Suppr");
							}
							catch (ObjetInconnuException e1)
							{
								e1.printStackTrace();
							}
						}
					}
				});
			}
			return jbRetirer;
		}

		/**
		 * Bouton permettant de confirmer l'achat des produits contenu dans le
		 * panier
		 * 
		 * @author Cedric
		 */
		public JButton getJbConfirmer()
		{
			if (jbConfirmer == null)
			{
				jbConfirmer = new JButton("Acheter le panier");
				jbConfirmer.addActionListener(new ActionListener()
				{
					public void actionPerformed(ActionEvent event)
					{
						if (Systeme.getInstance().getUtilisateur() == null)
						{
							new FrameConnexion().setVisible(true);

							if (Systeme.getInstance().getAchat() == null) Systeme
									.getInstance().setAchat(new Achat());
						}
						else
						{
							if (JOptionPane.showConfirmDialog(
									PanelVuePanier.this,
									"Commander les produits du panier?",
									"Confirmation", JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) acheter();
						}
					}
				});
			}
			return jbConfirmer;
		}

		public JButton getJbQuantite()
		{
			if (jbQuantite == null)
			{
				jbQuantite = new JButton("Quantité");
				jbQuantite.addActionListener(new ActionListener()
				{
					@Override
					public void actionPerformed(ActionEvent arg0)
					{
						int index = getJtProduits().getSelectedRow();

						if (index > -1)
						{
							try
							{
								Detail detail = panier.getDetail(index);
								if (detail != null)
								{
									String input = JOptionPane.showInputDialog(
											PanelVuePanier.this,
											"Quantité à acheter : ",
											detail.getQuantite());

									if (input != null)
									{
										int quantite = Integer.parseInt(input);

										if (quantite > 0)
										{
											try
											{
												if (quantite > Systeme
														.getInstance()
														.getStock()
														.getQuantiteProduit(
																detail.getProduit()))
												{
													JOptionPane
															.showMessageDialog(
																	PanelVuePanier.this,
																	"Le stock de \""
																			+ detail.getProduit()
																					.getTitre()
																			+ "\" n'est pas en quantité suffisante pour répondre à votre demande!",
																	"Opération impossible!",
																	JOptionPane.INFORMATION_MESSAGE);
												}
												else
												{
													panier.setQuantiteProduit(
															detail.getProduit(),
															quantite);
												}
											}
											catch (ObjetInconnuException e)
											{
												e.printStackTrace();
											}
										}
										else
										{
											JOptionPane.showMessageDialog(
													PanelVuePanier.this,
													"La quantité incorrecte!",
													"Erreur",
													JOptionPane.ERROR_MESSAGE);
										}
									}
								}
							}
							catch (NumberFormatException e)
							{
								JOptionPane.showMessageDialog(
										PanelVuePanier.this,
										"La quantité doit être un nombre!",
										"Erreur", JOptionPane.ERROR_MESSAGE);
							}
						}
					}
				});
			}
			return jbQuantite;
		}
	}
}
